#include "RS232.h"                 
//http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html#AEN125
//http://tech.groups.yahoo.com/group/ts-7000/message/7644
                 
RS232::RS232(char *com)
{
       perror("RS232::RS232()");
       
        /* open_input_source opens a device, sets the port correctly, and
           returns a file descriptor */
        fd1 = open(com, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK ); 
        
        if (fd1 <0) {perror(com); return; }
        
        
        if(tcgetattr(fd1,&oldtio)<0) /* save current serial port settings */
            perror("\tno tcget bull");
                                         
         //bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
        
        newtio = oldtio;
        newtio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
    	newtio.c_oflag &= ~OPOST;
    	newtio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
    	newtio.c_cflag &= ~(CSIZE|PARENB);
    	newtio.c_cflag |= CS8;
    	
        /* at least one char, but stop after 1 second */
    	newtio.c_cc[VTIME] = 0;
    	newtio.c_cc[VMIN] = 0;
    	/* No parity */
    	newtio.c_cflag &= ~(PARENB | PARODD);
        /* 
          BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
          CRTSCTS : output hardware flow control (only used if the cable has
                    all necessary lines. See sect. 7 of Serial-HOWTO)
          CS8     : 8n1 (8bit,no parity,1 stopbit)
          CLOCAL  : local connection, no modem contol
          CREAD   : enable receiving characters
        */
         
         //newtio.c_cflag = /*BAUDRATE | CRTSCTS |*/ CS8 | CLOCAL | CREAD;
         
        /*
          IGNPAR  : ignore bytes with parity errors
          ICRNL   : map CR to NL (otherwise a CR input on the other computer
                    will not terminate input)
          otherwise make device raw (no other input processing)
        */
                      // newtio.c_iflag = /*IGNPAR |*/ ICRNL;
         //newtio.c_iflag |= INPCK;
                          //         newtio.c_cflag &= ~CNEW_RTSCTS;
        /*
         Raw output.
        */
        
       	newtio.c_cflag &= ~(CRTSCTS);
        newtio.c_cflag &= ~(IXON | IXOFF | IXANY);
        newtio.c_oflag = 0;
        
        if(cfsetispeed(&newtio, BAUDRATE) < 0) perror("\tfucladfs");
        if(cfsetospeed(&newtio, BAUDRATE) < 0) perror("\tnullsdfa");

        /*
          ICANON  : enable canonical input
          disable all echo functionality, and don't send signals to calling program
        */
        // newtio.c_lflag = ICANON;
         
        /* 
          now clean the modem line and activate the settings for the port
        */
         tcflush(fd1, TCIFLUSH);
         
         if(tcsetattr(fd1,TCSANOW,&newtio) < 0) perror("\tno terminal set");
        
        //maxfd = MAX (fd1, fd2)+1;  /* maximum bit entry (fd) to test */
     
        /*
        FD_ZERO(&rdset);
		FD_ZERO(&wrset);
		FD_SET(sd, &rdset);
		FD_SET(ttyfd, &rdset);
	*/
		return;
} 
RS232::~RS232()
{
}

void RS232::process()
{
      //while (loop) {
            FD_ZERO(&readfs);
            FD_SET(fd1, &readfs);  /* set testing for source 1 */
            
            //  FD_SET(fd2, &readfs);  /* set testing for source 2 */
            /*
            buf[0] = 's';
            buf[1] = 't';
            buf[2] = 'f';
            buf[3] = 'u';
            */
            
           //write(fd1, buf, 5);
           //perror("\twrite it");

            if(select(FD_SETSIZE, &readfs, NULL, NULL, NULL) < 0) {
              perror ("\tselect < 0");
              return;
            }
            if (FD_ISSET(fd1, &readfs)) handle_input1();
       /* input from source 1 available */

}

void RS232::handle_input1()
{
     res = read(fd1, buf, 32);
     
     if(verbose_log)
        loghex("\tfd1", buf, res);
     
     //buf[res]=0;
     //printf(":%s:%d\n", buf, res);
 return;
}

unsigned char* RS232::getData(unsigned char* &buffer, int &len)
{
        // if(verbose_log)
      perror("RS232::getdata()");
    // printf("buffer size %d\n", buffers.size());
     
     if(res <= 0) 
     {
        perror("\tno data!");
        
        len = 0;
        
        buffer = NULL;
        
        return NULL;
     }
 //    if(&buffer
     buffer = buf;
     len = res;

     perror("\tfinished");
     return NULL;    
}

int RS232::sendData(unsigned char *buffer, int len)
{
    perror("RS232::sendData");
    loghex("\trs232: ", buffer, len);
    
    if(write(fd1, buffer, len) < 0) perror("\twrite error");
    
    return 0;
}

void RS232::loghex(char *what, unsigned char *buffer, int length)
{
	printf("%s: len: %d: ", what, length);
    int x = 0;
	
    if(buffer != NULL) 
	{
      for(x= 0; x < length; x++) printf("%02X ", buffer[x]);
    }
    
	printf("\n");
}

void RS232::ping()
{
      unsigned char byte = 'G';
     sendData(&byte, 1);
     
     return;
}
